package application;

import tools.Tool;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;

/**
 * Main view of the MiniDraw program which serves a both a view and a model.
 * The model component is specified below, and the view component displays the
 * image contents of the model.
 * 
 * To prevent screen flicker when drawing or resizing, an ImageBuffer is used.
 * All drawing from the associated tools is executed on imageBuffer, which is
 * drawn to screen on updates which are specified by the tools.
 */
@SuppressWarnings("serial")
public class CanvasView extends JComponent
{
	// Components
	public final Color BACKGROUND = Color.white;
	protected CanvasController Ccontroller;
	protected Image imageBuffer;
	protected Graphics imageBufferGraphics;
	protected int canvasWidth;
	protected int canvasHeight;
	protected Color penColor = Color.black;
	protected Tool currentTool;
	
	protected Graphics [] listOfObjects;
	protected Graphics [] obj;
	protected String currentToolName;
	protected int objectPosition, oldObject;
	protected Color [] objectColor;
	protected String [] objName;
	protected int [][] objLocation;
	protected int counter, counter2;
	
	// Constructor
	public CanvasView()
	{
		setBackground(BACKGROUND);
		Ccontroller = new CanvasController(this);
		addCanvasListener(Ccontroller);
		
		listOfObjects = new Graphics [100];
		objectPosition = -5;
		oldObject = -5;
		counter = 0;
		counter2 = 0;
		obj = new Graphics[100];
		objName = new String [100];
		objLocation = new int [100][4];
		objectColor = new Color [100];
	}
	
	protected void addCanvasListener(CanvasController listener)
	{
		if( listener != null )
		{
			addMouseListener((MouseListener) listener);
			addMouseMotionListener((MouseMotionListener) listener);
			addKeyListener((KeyListener) listener );
	    }
	}
	
	/****Drawing Methods*****************************************************/
	  /* (non-Javadoc)
	   * @see javax.swing.JComponent#update(java.awt.Graphics)
	   */
	  public void update(Graphics g){ paint(g);}
	  
	  /* (non-Javadoc)
	   * 
	   * Painting the DrawingCanvas is simply displaying the contents of the
	   * imageBuffer.
	   * 
	   * @see javax.swing.JComponent#paint(java.awt.Graphics)
	   */
	  public void paint(Graphics g) { g.drawImage(imageBuffer,0, 0, this);}
	  
	  
	  /**
	   * Paints over the drawing canvas in the background color
	   */
	  public void clearCanvas()
	  {
		imageBufferGraphics.setColor(BACKGROUND);
		imageBufferGraphics.fillRect(0, 0, canvasWidth, canvasHeight);
		imageBufferGraphics.setColor(penColor);
		repaint();
		
		for(int count = 0; count < obj.length; count++)
		{
			obj[count].dispose();
			listOfObjects[count].dispose();
		}
	  }
	  
	  /****Accessor and Update Methods*****************************************/
	  
	  /**
	   * Updates the current drawing color
	   * 
	   * @param c new drawing color
	   */
	  public void setpenColor(Color c)
	  {
		  if( c != null )
		  {	
			  penColor = c;
			  imageBufferGraphics.setColor(c);
		  }
	  }
	    
	  /**
	   * Accessor method for current drawing color
	   * 
	   * @return current drawing color
	   */
	  public Color getpenColor(){ return penColor; }
	  
	  /**
	   * Updates current drawing tool
	   * 
	   * @param t new drawing tool
	   */
	  public void setcurrentTool(Tool t, String name)
	  {
		  currentToolName = name;
		  
		  if( t != null )
			  currentTool = t;
	  }
	  
	  public void addGraphic(Graphics g)
	  {
		  obj[counter2] = g;
		  objectColor[counter2++] = g.getColor();
	  }
	  
	  public void addToList(String type, int [][] objSize)
	  {
		  Graphics g = getGraphics();
		  objLocation = objSize;
		  objName = getCanvasShapes();
		  
		  int width = objLocation[counter][2] - objLocation[counter][0];
		  int height = objLocation[counter][3] - objLocation[counter][1];
		  
		  g.setColor(penColor);
		  if("Rectangle".equals(type))
			  g.drawRect(objLocation[counter][0], objLocation[counter][1], width + 1, height + 1);
		  	
		  listOfObjects[counter++] = g;
	  }
	  
	  public String [] getCanvasShapes(){ return Ccontroller.getShapeType(); }
	  public int [][] getCanvasPositions(){ return Ccontroller.getPositions(); }
	  public void setShapeColor(int shape){ objectColor[shape] = penColor; }
	  public void setCanvasObject(int temp, String name)
	  { 
		  objectPosition = temp;
	  	  
		  Graphics g = getGraphics();
		  g.setColor(Color.lightGray);
		  int width = objLocation[objectPosition][2] - objLocation[objectPosition][0];
		  int height = objLocation[objectPosition][3] - objLocation[objectPosition][1];
		  
		  if("Rectangle".equals(name))
		  {
			  g.drawRect(objLocation[objectPosition][0], objLocation[objectPosition][1], width + 1, height + 1);
		  }
		  
		  if(oldObject != -5)
		  {
			  g.setColor(objectColor[oldObject]);
			  width = objLocation[oldObject][2] - objLocation[oldObject][0];
			  height = objLocation[oldObject][3] - objLocation[oldObject][1];
			  if("Rectangle".equals(objName[oldObject]))
			  {
				  g.drawRect(objLocation[oldObject][0], objLocation[oldObject][1], width + 1, height + 1);
			  }
		  }
		  oldObject = objectPosition;
		  
	  }
	  public int getCanvasobject(){ return objectPosition; }
	  
	  public void changeObjectColor(Color toColor)
	  {

		  	Graphics g = listOfObjects[objectPosition];
		  	Graphics g2 = obj[objectPosition];
		  
		  	objLocation = getCanvasPositions();
		  	objName = getCanvasShapes();
		  	
		  	int width = objLocation[objectPosition][2] - objLocation[objectPosition][0];
		  	int height = objLocation[objectPosition][3] - objLocation[objectPosition][1];
		  	
		  	objectColor[objectPosition] = toColor;
	  		g.setColor(toColor);
	  		g2.setColor(toColor);
		  	if("Rectangle".equals(objName[objectPosition]))
		  	{
		  		g.drawRect(objLocation[objectPosition][0], objLocation[objectPosition][1], width + 1, height + 1);
		  		g2.drawRect(objLocation[objectPosition][0], objLocation[objectPosition][1], width + 1, height + 1);
		  	}
		  	
		  	listOfObjects[objectPosition] = g;
		  	obj[objectPosition] = g2;

	  }
	  
	  /**
	   * Accessor method for current drawing tool
	   * 
	   * @return current drawing tool
	   */
	  public Tool getcurrentTool(){ return currentTool; }
	  
	  /**
	   * Accessor method for the name of the current tool
	   * 
	   * @return current tool's name
	   */
	  public String getCurrentToolName(){return currentToolName;}
	  
	  /**
	   * Accessor method for imageBuffer
	   * 
	   * @return current image buffer graphics context
	   */
	  public Graphics getimageBufferGraphics(){ return imageBufferGraphics; }
	  
	  
	  /* (non-Javadoc)
	   * 
	   * Adjusts the size of the DrawingCanvas as well as the imageBuffer to match
	   * the new DrawingCanvas size.
	   * 
	   * @see java.awt.Component#setBounds(int, int, int, int)
	   */
	  public void setBounds(int x, int y, int width, int height)
	  {
		  Image newimageBuffer = createImage(width, height);
		  imageBufferGraphics = newimageBuffer.getGraphics();
		  if (imageBuffer != null)
		  {
			  imageBufferGraphics.drawImage(imageBuffer, 0, 0 ,this);
		  }
		  imageBuffer = newimageBuffer;
		  setpenColor(penColor);
		  super.setBounds(x, y, width, height);
		  repaint();
		  canvasWidth = width;
		  canvasHeight = height;
	  }
}
